package com.leyou.search.web;


import com.leyou.search.demo.Item;
import com.leyou.search.repository.ItemRepository;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wgc
 * @create 2019-07-26 22:29
 */
@RestController
public class ElasticsearchController {
    protected static Logger logger = LoggerFactory.getLogger(ElasticsearchController.class);

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private ItemRepository itemRepository;
    @PostMapping("testCreate")
    public void testCreate(){
        // 创建索引，会根据Item类的@Document注解信息来创建
        elasticsearchTemplate.createIndex(Item.class);
        logger.info("创建索引成功--------------");
        // 配置映射，会根据Item类中的id、Field等字段来自动完成映射
        elasticsearchTemplate.putMapping(Item.class);
        logger.info("配置映射成功--------------");

    }

    @PostMapping("index")
    public void index() {
        Item item = new Item(1L, "小米手机7", " 手机",
                "小米", 3499.00, "http://image.leyou.com/13123.jpg");
        Item save = itemRepository.save(item);
        logger.info("新增数据成功--------------"+save);
    }
    @PostMapping("indexList")
    public void indexList() {
        List<Item> list = new ArrayList<>();
        list.add(new Item(2L, "坚果手机R1", " 手机", "锤子", 3699.00, "http://image.leyou.com/123.jpg"));
        list.add(new Item(3L, "华为META10", " 手机", "华为", 4499.00, "http://image.leyou.com/3.jpg"));
        // 接收对象集合，实现批量新增
        Iterable<Item> items = itemRepository.saveAll(list);

        logger.info("批量新增数据成功--------------"+items);
    }


    @PostMapping("findAll")
    public void findAll() {
          // 接收对象集合，实现批量新增
        Iterable<Item> items = itemRepository.findAll();

        logger.info("批量新增数据成功--------------"+items);
        for(Item item:items){
            System.out.println(item.getTitle());
        }
    }

    @PostMapping("findByCondition")
    public void testFind(){
        // 查询全部，并安装价格降序排序
        Iterable<Item> items = this.itemRepository.findAll(Sort.by(Sort.Direction.DESC, "price"));
        items.forEach(item-> System.out.println(item));
    }

    @PostMapping("findByPriceBetween")
    public void findByPriceBetween(){
        // 查询全部，并安装价格降序排序
        Iterable<Item> items = this.itemRepository.findByPriceBetween(3000.00,4000.00);
        items.forEach(item-> System.out.println(item));
    }


    //原生查询
    @PostMapping("testQuery")
    public void testQuery(){
        // 词条查询
        MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "小米");
        // 执行查询
        Iterable<Item> items = this.itemRepository.search(queryBuilder);
        items.forEach(System.out::println);
    }

    @RequestMapping("testNativeQuery")
    public void testNativeQuery(){
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词查询
        queryBuilder.withQuery(QueryBuilders.matchQuery("title", "小米"));
        queryBuilder.withPageable(PageRequest.of(0, 3));
        // 执行搜索，获取结果
        Page<Item> items = this.itemRepository.search(queryBuilder.build());
        // 打印总条数
        System.out.println(items.getTotalElements());
        // 打印总页数
        System.out.println(items.getTotalPages());
        items.forEach(System.out::println);
    }

    @RequestMapping("testNativeQueryByPage")
    public void testNativeQueryByPage(){
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词查询
        queryBuilder.withQuery(QueryBuilders.termQuery("category", "手机"));

        // 初始化分页参数
        int page = 0;
        int size = 3;
        // 设置分页参数
        queryBuilder.withPageable(PageRequest.of(page, size));

        // 执行搜索，获取结果
        //elasticsearchTemplate.queryForPage(queryBuilder.build(),Item.class);
        Page<Item> items = this.itemRepository.search(queryBuilder.build());
        // 打印总条数
        System.out.println(items.getTotalElements());
        // 打印总页数
        System.out.println(items.getTotalPages());
        // 每页大小
        System.out.println(items.getSize());
        // 当前页
        System.out.println(items.getNumber());
        List<Item> content = items.getContent();
        content.forEach(System.out::println);
    }


    @RequestMapping("AggregatedPage")
    public void testAggregatedPage(){
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 添加基本的分词查询
        queryBuilder.addAggregation(AggregationBuilders.terms("popularBrand").field("brand"));
        // 初始化分页参数
       /* int page = 0;
        int size = 3;
        // 设置分页参数
        queryBuilder.withPageable(PageRequest.of(page, size));
*/
        // 执行搜索，获取结果
        AggregatedPage<Item> items = elasticsearchTemplate.queryForPage(queryBuilder.build(), Item.class);
        //Page<Item> items = this.itemRepository.search(queryBuilder.build());
        // 打印总条数
        System.out.println(items.getTotalElements());
        // 打印总页数
        System.out.println(items.getTotalPages());
        // 每页大小
        System.out.println(items.getSize());
        // 当前页
        System.out.println(items.getNumber());
        //解析聚合
        Aggregations aggregations = items.getAggregations();
        //获取指定聚合的名称
        StringTerms popularBrand = aggregations.get("popularBrand");
        //获取桶
        List<StringTerms.Bucket> buckets = popularBrand.getBuckets();
        for (StringTerms.Bucket bucket : buckets) {
            System.out.println("---------bucket.getKeyAsString()--------"+bucket.getKeyAsString());
            System.out.println("---------bucket.getDocCount()--------"+bucket.getDocCount());

        }
    }
}
